﻿using Spire.Pdf;
using Spire.Pdf.Graphics;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SuperKit
{
    public class UnzipPDF : CommandExecutor {
        public class UnzipPDFItem : ThreadToolItem {
            public UnzipPDF Parent { get; }
            public FileInfo File { get; }

            public UnzipPDFItem(UnzipPDF parent, FileInfo file) {
                this.Parent = parent;
                this.File = file;
            }


            public override void Process() {
                Parent.Unzip(File);
            }

            public override string ToString() {
                return File.Name;
            }
        }

        public string DEFAULT_DIR = "(_UNZIP)";
        public ThreadTool<UnzipPDFItem> Files;
        public string password;

        public UnzipPDF(ArgReader arg, IExecutorOwner form, string fpath) : base(arg, form, fpath) {
            password = arg.GetParameter("-pwd");
        }

        public List<FileInfo> TargetList { get; private set; }
        public override void Execute() {
            base.Execute();
            TargetList = new List<FileInfo>();
            GetAllFiles(new DirectoryInfo(FilePath), TargetList, Kit.PDF_EXTS);
            Thread t = new Thread(StartClear);
            t.Start();
        }

        private void StartClear() {
            Files = new ThreadTool<UnzipPDFItem>(MaxThread, SetStatus);           

            foreach (var i in TargetList) {
                Files.Add(new UnzipPDFItem(this, i));
            }

            Files.Start();

            End();
        }

        private string CalculateOutput(string file, int index) {
            // 获得自已的特有目录
            var ownerStart = FilePath.Length + 1;
            var ownerPath = file.Substring(ownerStart);
            var extIndex = ownerPath.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase);
            if (extIndex != -1) {
                ownerPath = ownerPath.Substring(0, extIndex).Trim();
            }

            //var pure = Path.GetFileNameWithoutExtension(file);
            var output = TargetDir;
            var dir = string.Empty;
            if (Kit.IsEmpty(output)) {
                dir = Path.Combine(FilePath, DEFAULT_DIR, ownerPath);
            } else {
                dir = Path.Combine(output, ownerPath);
            }
            if (Directory.Exists(dir) == false) {
                Directory.CreateDirectory(dir);
            }
            return Path.Combine(dir, string.Format("{0:D4}.png", index));
        }




        private void Unzip(FileInfo file) {
            PdfDocument doc;
            if (Kit.IsEmpty(password)) {
                doc = new PdfDocument(file.FullName);
            } else {
                doc = new PdfDocument(file.FullName, password);
            }
            for (int i = 0; i < doc.Pages.Count; i++) {
                var savePath = CalculateOutput(file.FullName, i);
                if (File.Exists(savePath)) {
                    Flush("{0} 已经存在！", savePath);
                    continue;
                }

                var page = doc.Pages[i];
                Image[] images = page.ExtractImages();
                if (images == null || images.Length == 0) {
                    continue;
                }

                Image img1 = images[0];
                Bitmap saveImg = new Bitmap(img1, img1.Size.Width, img1.Size.Height);

                try {
                    saveImg.Save(savePath, ImageFormat.Png);
                } catch (Exception e) {
                    Flush($"{savePath} Error: \n{e.ToString()}");
                }

                //img.Save(savePath);
                SetStatus(savePath);
                img1.Dispose();
                saveImg.Dispose();
            }
            doc.Close();
        }

        //图片转换
        public static Bitmap saveBMP(MemoryStream ms1) {
            Bitmap bmp = (Bitmap)Image.FromStream(ms1);
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
            ImageLockMode.WriteOnly, bmp.PixelFormat);
            //用Marshal的Copy方法，将刚才得到的内存字节数组复制到BitmapData中
            var imgBytes = ms1.ToArray();
            System.Runtime.InteropServices.Marshal.Copy(imgBytes, 0, bmpData.Scan0, imgBytes.Length);
            //解锁内存区域  
            bmp.UnlockBits(bmpData);
            return bmp;
        }

        //图片转换
        public static Bitmap buildBMP(byte[] imgBytes) {
            MemoryStream ms1 = new MemoryStream(imgBytes);
            Bitmap bmp = (Bitmap)Image.FromStream(ms1);
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
            ImageLockMode.WriteOnly, bmp.PixelFormat);
            //用Marshal的Copy方法，将刚才得到的内存字节数组复制到BitmapData中
            System.Runtime.InteropServices.Marshal.Copy(imgBytes, 0, bmpData.Scan0, imgBytes.Length);
            //解锁内存区域  
            bmp.UnlockBits(bmpData);
            return bmp;
        }

        //图片装换
        public static Bitmap buildBMP(int width, int height, byte[] imgBytes) {
            Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
             ImageLockMode.WriteOnly, bmp.PixelFormat);
            //用Marshal的Copy方法，将刚才得到的内存字节数组复制到BitmapData中
            System.Runtime.InteropServices.Marshal.Copy(imgBytes, 0, bmpData.Scan0, imgBytes.Length);
            //解锁内存区域  
            bmp.UnlockBits(bmpData);
            return bmp;
        }
    }
}
